﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Threading.Tasks;
using MVVMCommon.ViewModels.Commands;
using System.Reactive.Linq;
using System.ComponentModel;

namespace FlashlightRecorder.ViewModels
{
    public class Recorder_Model : DisposableHost, INotifyPropertyChanged
    {
        public Recorder_Model()
        {
            RecordSingnalCommand = new ReactiveCommand(false);
            StartRecordCommand = new ReactiveCommand(true);
            StopRecordCommand = new ReactiveCommand(false);
            SaveRecordCommand = new ReactiveCommand(false);
            ClearRecordCommand = new ReactiveCommand(false);
            RecordingTarget = new Record() { Name = "New Chip" };
            BeginInitActions();
        }
        public Repositories.SimpleRepository<Record> RecordRepository { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public ReactiveCommand RecordSingnalCommand { get; private set; }
        public ReactiveCommand StartRecordCommand { get; private set; }
        public ReactiveCommand StopRecordCommand { get; private set; }
        public ReactiveCommand SaveRecordCommand { get; private set; }
        public ReactiveCommand ClearRecordCommand { get; private set; }

        void BeginInitActions()
        {


            var rcd = Observable.FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                    ac => (s, e) => ac(e),
                    eh => this.PropertyChanged += eh,
                    eh => this.PropertyChanged -= eh
                )
                .Where(x => x.PropertyName == "IsRecording");


            rcd
                .Select(e => IsRecording)
                .Subscribe(StopRecordCommand)
                .RegisterDispose(this);

            rcd
                .Select(e => IsRecording)
                .Subscribe(RecordSingnalCommand)
                .RegisterDispose(this);

            rcd
                .Select(e => !IsRecording)
                .Subscribe(StartRecordCommand)
                .RegisterDispose(this);
            rcd
                .Select(e => !IsRecording)
                .Where(_ => RecordingTarget.Items.Count > 0)
                .Subscribe(SaveRecordCommand)
                .RegisterDispose(this);

            rcd
                .Select(e => !IsRecording)
                .Where(_ => RecordingTarget.Items.Count > 0)
                .Subscribe(ClearRecordCommand)
                .RegisterDispose(this);

            StartRecordCommand
                .Subscribe(
                    _ =>
                    {
                        _startTime = DateTime.Now;
                        IsRecording = true;
                    }
                )
                .RegisterDispose(this);

            StopRecordCommand
                .Subscribe(
                    _ =>
                    {
                        IsRecording = false;
                        RecordingTarget.Duration = DateTime.Now - _startTime;
                        Root.PlayerModel.CurrentRecord = RecordingTarget;
                    }
                )
                .RegisterDispose(this);

            RecordSingnalCommand
                .Subscribe(
                    hit =>
                    {
                        bool isHit = bool.Parse((string)hit);
                        if (isHit)
                        {
                            _currentOne = new LightSpan();
                            _currentOne.Start = DateTime.Now - _startTime;
                            RecordingTarget.Items.Add(_currentOne);
                        }
                        else
                        {
                            if (_currentOne != null)
                            {
                                _currentOne.Duration = (DateTime.Now - _startTime) - _currentOne.Start;
                            }
                        }

                    }
                )
                .RegisterDispose(this);

            ClearRecordCommand
                .Subscribe(
                    _ =>
                    {

                        RecordingTarget = new Record();
                    }
                )
                .RegisterDispose(this);

            SaveRecordCommand
                .Subscribe(
                  async  _ =>
                    {
                        await RecordRepository.SetOrUpdateByKeyAsync(RecordingTarget.Name, RecordingTarget);
                        App.ViewModel.LoadItemsAsync();
                    }
                )
                .RegisterDispose(this);

        }

        LightSpan _currentOne;


        public MainViewModel Root { get; set; }


        DateTime _startTime;

        bool _isRecording;



        public bool IsRecording
        {
            get { return _isRecording; }
            set { _isRecording = value; NotifyPropertyChanged("IsRecording"); }
        }





        Record _recordingTarget;
        public Record RecordingTarget
        {
            get { return _recordingTarget; }
            set { _recordingTarget = value; NotifyPropertyChanged("RecordingTarget"); }
        }
    }
}
